package cn.iocoder.boot.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.iocoder.boot.dto.ImportStockTO;
import cn.iocoder.boot.dto.LibraryDTO;
import cn.iocoder.boot.entity.ComponentPrice;
import cn.iocoder.boot.entity.ComponentStock;
import cn.iocoder.boot.entity.ComponentSupplier;
import cn.iocoder.boot.mapper.ComponentPriceMapper;
import cn.iocoder.boot.mapper.ComponentStockMapper;
import cn.iocoder.boot.service.ComponentPriceService;
import cn.iocoder.boot.service.ComponentStockService;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.extension.toolkit.Db.*;

@Service
@DS("master")
@Slf4j
public class ComponentStockServiceImpl implements ComponentStockService {

    @Autowired
    private ComponentStockMapper baseMapper;

    @Resource
    private ComponentPriceService componentPriceService;

    @Resource
    private ComponentSupplierServiceImpl componentSupplierservice;

    @Value("${libiryUrl}")
    private String libiryUrl;

    @Resource
    private ComponentPriceMapper componentPriceMapper;

    @Override
    public boolean saveComponentStock(ComponentStock componentStock) {
        return save(componentStock);
    }

    @Override
    public List<ComponentStock> getListByIds(List<Long> ids) {

        List<ComponentStock> listByIds = listByIds(ids, ComponentStock.class);
        return listByIds;
    }


    @Override
    public List<ComponentStock> getListByModels(List<String> models) {
        return baseMapper.getListByModels(models);
    }


    @Override
    public boolean saveComponentStockBranch(List<ComponentStock> componentStock) {

        return saveBatch(componentStock);
    }

    @Override
    public boolean updateComponentStock(ComponentStock componentStock) {
        componentStock.setStockType(2);
        componentStock.setSource(2);

        Map<String, Object> map = new HashMap<>();
        map.put("stock_id", componentStock.getId());
        componentPriceMapper.deleteByMap(map);

        ComponentStock queryComponentStock = baseMapper.selectById(componentStock.getId());
        List<ComponentPrice> list = new ArrayList<>();
        for (ComponentPrice price : componentStock.getPriceList()) {
            price.setStockId(componentStock.getId());
            price.setStock(componentStock.getStock());
            price.setType(2);
            price.setUniqueId(queryComponentStock.getUniqueId());
            list.add(price);
        }
        componentPriceService.createComponentPriceBranch(list);

        return updateById(componentStock);
    }

    @Override
    public boolean deleteComponentStock(Long id) {
        baseMapper.deleteById(id);
        return true;
    }

    @Override
    public ComponentStock getComponentStock(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    public PageResult<ComponentStock> listComponentStocks(PageParam pageParam, Wrapper<ComponentStock> queryWrapper) {
        IPage<ComponentStock> page = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        page = baseMapper.selectPage(page, queryWrapper);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    @Override
    public Boolean insertComponentStock(ComponentStock componentStock) {
        componentStock.setStockType(2);
        //防止报错
        componentStock.setDeleted(null);

        componentStock.setSource(2);
        String uniqueId = componentStock.getSupplierCode() + "_" + UUID.randomUUID().toString().replace("-", "");
        componentStock.setUniqueId(uniqueId);

        save(componentStock);
        List<ComponentPrice> priceList = new ArrayList<>();
        for (ComponentPrice price : componentStock.getPriceList()) {
            price.setStockId(componentStock.getId());
            price.setType(2);
            price.setStock(componentStock.getStock());
            price.setUniqueId(uniqueId);
            price.setExpireDate(LocalDateTime.now().plusYears(20));
            priceList.add(price);
        }

        componentPriceService.createComponentPriceBranch(priceList);


        return true;
    }

    @Override
    public Boolean importComponentStock(MultipartFile file) throws IOException {
        Map<String, List<ImportStockTO>> sheetDataMap = new HashMap<>();

        // 使用 Apache POI 获取所有 sheet 名称
        try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
            int numberOfSheets = workbook.getNumberOfSheets();

            for (int i = 0; i < numberOfSheets; i++) {
                Sheet sheet = workbook.getSheetAt(i);
                String sheetName = sheet.getSheetName();

                // 重新读取该 sheet 数据（每次读取需要重新打开流）
                try (InputStream inputStream = file.getInputStream()) {
                    List<ImportStockTO> sheetData = new ArrayList<>();
                    EasyExcel.read(inputStream, ImportStockTO.class, new PageReadListener<ImportStockTO>(dataList -> {
                        sheetData.addAll(dataList);
                    })).sheet(i).doRead();

                    sheetDataMap.put(sheetName, sheetData);
                }
            }
        } catch (Exception e) {
            log.error("导入库存组件失败", e);
            return false;
        }
        List<ComponentSupplier> list = componentSupplierservice.getList();
        List<String> names = list.stream()
                .map(ComponentSupplier::getName) // 提取 name 字段
                .collect(Collectors.toList());


        return true;
    }


    public void intoLibrary() {
        // 筛选出还没入国创的数据，得捷，易络盟，昴氏
        QueryWrapper<ComponentStock> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("library_status", 0)
                .in("supplier_code", "VEND0004", "VEND0005", "VEND0006");

        // 分页参数
        int pageSize = 500;
        int currentPage = 1;

        // 循环分页查询数据
        while (true) {
            // 分页查询
            Page<ComponentStock> page = new Page<>(currentPage, pageSize);
            Page<ComponentStock> resultPage = baseMapper.selectPage(page, queryWrapper);
            List<ComponentStock> componentStockList = resultPage.getRecords();

            // 如果没有数据，跳出循环
            if (componentStockList.isEmpty()) {
                break;
            }

            // 使用 Set 进行去重（根据 model 和 supplierCode 去重）
            Set<String> seenModels = new HashSet<>();
            List<ComponentStock> uniqueComponentStockList = componentStockList.stream()
                    .filter(componentStock -> seenModels.add(componentStock.getModel() + componentStock.getSupplierCode()))
                    .collect(Collectors.toList());

            // 转换为 LibraryDTO 列表
            List<LibraryDTO> dtos = new ArrayList<>();
            for (ComponentStock componentStock : uniqueComponentStockList) {
                LibraryDTO dto = new LibraryDTO();
                dto.setKbComponentStockId(componentStock.getId().toString());
                dto.setPartNumber(componentStock.getModel());
                LibraryDTO.TemplateFieldBean bean = new LibraryDTO.TemplateFieldBean();

                bean.setKey0(componentStock.getModel());
                bean.setKey1(componentStock.getBrand());
                bean.setKey7(componentStock.getSpecifications());
                bean.setKey12(componentStock.getType());

                dto.setDataSource(componentStock.getStockType() == 1 ? "API" : "kb-components");

                dto.setTemplateFieldBean(bean);
                dtos.add(dto);
            }

            // 转换为 JSON 字符串
            String jsonBody = JSONUtil.toJsonStr(dtos);
            log.info("定时同步国创请求体：" + jsonBody);

            // 使用 Hutool 发送 POST 请求
            String response = HttpRequest.post(libiryUrl)
                    .header("Content-Type", "application/json") // 设置请求头为 JSON
                    .body(jsonBody) // 设置请求体
                    .execute()
                    .body(); // 获取响应体

            // 输出返回的响应
            log.info("定时同步国创返回结果：" + response);

            // 如果当前页的记录数小于 pageSize，说明已经查询完所有数据，跳出循环
            if (componentStockList.size() < pageSize) {
                break;
            }

            // 否则，切换到下一页
            currentPage++;
        }
    }

    @Override
    public void saveComponentStockOfUniqueKey(ComponentStock componentStock) {
        baseMapper.saveComponentStockOfUniqueKey(componentStock);
    }


}
